﻿/*************************************************************************
 * R-Tree/R*-Tree 访问器
 * 
 * @author lmliang@live.cn
 *************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RStarTree
{
    /// <summary>
    /// R*-Tree
    /// </summary>
    /// <typeparam name="TLeaf">叶子类型</typeparam>
    partial class RStarTree<TLeaf>
    {
        /// <summary>
        /// 接收器
        /// </summary>
        /// <typeparam name="TLeaf">叶子类型</typeparam>
        interface IRTreeAccepter<TLeaf>
        {
            /// <summary>
            /// 分支节点是否接收
            /// </summary>
            /// <param name="node">分支节点</param>
            /// <returns>接收返回true，否则返回false</returns>
            Boolean Accept(RTreeNode node);

            /// <summary>
            /// 叶子节点是否接收
            /// </summary>
            /// <param name="leaf">叶子节点</param>
            /// <returns>接收返回true，否则返回false</returns>
            Boolean Accept(RTreeLeaf<TLeaf> leaf);
        }

        /// <summary>
        /// 任意叶子接收器
        /// </summary>
        /// <typeparam name="TLeaf">叶子类型</typeparam>
        class RTreeAnyAccepter<TLeaf> : IRTreeAccepter<TLeaf>
        {
            public RTreeAnyAccepter()
            {
            }

            public Boolean Accept(RTreeNode node)
            {
                return true;
            }

            public Boolean Accept(RTreeLeaf<TLeaf> leaf)
            {
                return true;
            }
        }

        /// <summary>
        /// 完全包含叶子接收器
        /// </summary>
        /// <typeparam name="TLeaf">叶子类型</typeparam>
        class RTreeEnclosedAccepter<TLeaf> : IRTreeAccepter<TLeaf>
        {
            /// <summary>
            /// 构造
            /// </summary>
            /// <param name="bound">查询包围盒</param>
            public RTreeEnclosedAccepter(RTreeBoundingBox bound)
            {
                searchBound = bound;
            }

            public Boolean Accept(RTreeNode node)
            {
                return searchBound.Overlapped(node);
            }
            public Boolean Accept(RTreeLeaf<TLeaf> leaf)
            {
                if (searchBound.Enclosed(leaf))
                    return true;
                else
                    return false;
            }

            private RTreeBoundingBox searchBound;
        }

        /// <summary>
        /// 相交覆盖叶子接收器
        /// </summary>
        /// <typeparam name="TLeaf">叶子类型</typeparam>
        class RTreeOverlappedAccepter<TLeaf> : IRTreeAccepter<TLeaf>
        {
            /// <summary>
            /// 构造
            /// </summary>
            /// <param name="bound">查询包围盒</param>
            public RTreeOverlappedAccepter(RTreeBoundingBox bound)
            {
                searchBound = bound;
            }

            public Boolean Accept(RTreeNode node)
            {
                return searchBound.Overlapped(node);
            }
            public Boolean Accept(RTreeLeaf<TLeaf> leaf)
            {
                if (searchBound.Overlapped(leaf))
                    return true;
                else
                    return false;
            }

            private RTreeBoundingBox searchBound;
        }

        /// <summary>
        /// 删除器
        /// </summary>
        /// <typeparam name="TLeaf">叶子类型</typeparam>
        interface IRTreeRemover<TLeaf>
        {
            /// <summary>
            /// 是否继续
            /// </summary>
            /// <returns>继续返回true，否则返回false</returns>
            Boolean Continue();

            /// <summary>
            /// 分支节点删除
            /// </summary>
            /// <param name="node">分支节点</param>
            /// <returns>可删除返回true，否则返回false</returns>
            //Boolean Remove(RTreeNode node);

            /// <summary>
            /// 叶节点删除
            /// </summary>
            /// <param name="leaf">叶节点</param>
            /// <returns>可删除返回true，否则返回false</returns>
            Boolean Remove(RTreeLeaf<TLeaf> leaf);
        }

        /// <summary>
        /// 任意叶子删除器
        /// </summary>
        /// <typeparam name="TLeaf">叶子类型</typeparam>
        class RTreeAnyLeafRemover<TLeaf> : IRTreeRemover<TLeaf>
        {
            public Boolean Continue()
            {
                return true;
            }

            public Boolean Remove(RTreeLeaf<TLeaf> leaf)
            {
                return true;
            }
        }

        /// <summary>
        /// 指定叶子删除器
        /// </summary>
        /// <typeparam name="TLeaf">叶子类型</typeparam>
        class RTreeSpecificLeafRemover<TLeaf> : IRTreeRemover<TLeaf>
        {
            /// <summary>
            /// 构造
            /// </summary>
            /// <param name="removeLeaf">待删除叶子</param>
            /// <param name="removeDuplicates">是否删除重复叶子</param>
            public RTreeSpecificLeafRemover(TLeaf removeLeaf, Boolean removeDuplicates = false)
            {
                this.removeLeaf = removeLeaf;
                this.removeDuplicates = removeDuplicates;
                this.continues = true;
            }

            public Boolean Continue()
            {
                return continues;
            }

            public Boolean Remove(RTreeLeaf<TLeaf> leaf)
            {
                if (continues && object.Equals(removeLeaf, leaf.Leaf))
                {
                    // 如果不删除重复叶子，则不继续
                    if (!removeDuplicates)
                        continues = false;

                    return true;
                }
                else
                    return false;
            }

            private TLeaf removeLeaf;
            private Boolean removeDuplicates;
            private Boolean continues;
        }
    }
}
